package com.example.demo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.base.config.auth.UserInfoShareHolder;
import com.example.demo.base.login.dto.UserCache;
import com.example.demo.common.IdParam;
import com.example.demo.common.ObjectiveQuestionItem;
import com.example.demo.constants.BusinessExceptionCode;
import com.example.demo.constants.Constants;
import com.example.demo.constants.RedisKey;
import com.example.demo.domain.entity.*;
import com.example.demo.dto.ObjectiveQuestionDTO;
import com.example.demo.dto.VojObjectiveQuestionsDto;
import com.example.demo.dto.VojObjectiveQuestionsListDto;
import com.example.demo.enums.UserIdentifyEnum;
import com.example.demo.exception.BusinessException;
import com.example.demo.exception.ExceptionUtils;
import com.example.demo.mapper.*;
import com.example.demo.param.voj.VojObjectiveQuestionsListParam;
import com.example.demo.param.voj.VojObjectiveQuestionsSaveParam;
import com.example.demo.service.VojObjectiveQuestionAnswerService;
import com.example.demo.service.VojObjectiveQuestionOptionService;
import com.example.demo.service.VojObjectiveQuestionsCategoryRelationshipsService;
import com.example.demo.service.VojObjectiveQuestionsService;
import com.example.demo.utils.JsonUtils;
import com.example.demo.utils.RedisUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author 00774904
* @description 针对表【voj_objective_questions】的数据库操作Service实现
* @createDate 2023-11-17 16:43:55
*/
@Service
public class VojObjectiveQuestionsServiceImpl extends ServiceImpl<VojObjectiveQuestionMapper, VojObjectiveQuestion>
    implements VojObjectiveQuestionsService{


    @Resource
    private VojObjectiveQuestionMapper vojObjectiveQuestionMapper;
    @Resource
    private VojObjectiveQuestionsCategoryRelationshipsMapper vojObjectiveQuestionsCategoryRelationshipsMapper;
    @Resource
    private VojObjectiveQuestionsTagRelationshipsMapper vojObjectiveQuestionsTagRelationshipsMapper;
    @Resource
    private VojObjectiveQuestionsTagRelationshipsServiceImpl vojObjectiveQuestionsTagRelationshipsService;
    @Resource
    private VojObjectiveQuestionsCategoryRelationshipsService vojObjectiveQuestionsCategoryRelationshipsService;
    @Resource
    private VojObjectiveQuestionOptionMapper vojObjectiveQuestionOptionMapper;
    @Resource
    private VojObjectiveQuestionAnswerMapper vojObjectiveQuestionAnswerMapper;
    @Resource
    private VojObjectiveQuestionOptionService vojObjectiveQuestionOptionService;
    @Resource
    private VojObjectiveQuestionAnswerService vojObjectiveQuestionAnswerService;
    @Resource
    private RedisUtil redisUtil;


    @Override
    public void save(VojObjectiveQuestionsSaveParam param){
        Long companyId = UserInfoShareHolder.getUserInfo().getCompanyId();
        VojObjectiveQuestion entity = BeanUtil.copyProperties(param, VojObjectiveQuestion.class);
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        User user = userInfo.getUser();
        entity.setCreatorId(user.getId());
        if (null == entity.getCompanyId()){
            entity.setCompanyId(companyId);
        }
        entity.setModifyTime(DateUtil.date().toTimestamp());
        if (null == param.getId()){
            entity.setCreateTime(DateUtil.date().toTimestamp());
            vojObjectiveQuestionMapper.insert(entity);
            vojObjectiveQuestionMapper.modifyId(entity.getId());
            // 修改id值，因为自增id过大，而且默认值修改不成功（）
            entity.setId(entity.getId() - 1767810562105821460L);
        }else {
            // 删除原库中数据(选项+答案+分类+标签)
            QueryWrapper<VojObjectiveQuestionsCategoryRelationships> categoryWrapper = new QueryWrapper<>();
            categoryWrapper.eq("question_id", entity.getId());
            QueryWrapper<VojObjectiveQuestionsTagRelationships> tagWrapper = new QueryWrapper<>();
            tagWrapper.eq("question_id", entity.getId());
            QueryWrapper<VojObjectiveQuestionAnswer> answerWrapper = new QueryWrapper<>();
            answerWrapper.eq("question_id", entity.getId());
            QueryWrapper<VojObjectiveQuestionOption> optionWrapper = new QueryWrapper<>();
            optionWrapper.eq("question_id", entity.getId());
            vojObjectiveQuestionsCategoryRelationshipsMapper.delete(categoryWrapper);
            vojObjectiveQuestionsTagRelationshipsMapper.delete(tagWrapper);
            vojObjectiveQuestionAnswerMapper.delete(answerWrapper);
            vojObjectiveQuestionOptionMapper.delete(optionWrapper);
            vojObjectiveQuestionMapper.updateById(entity);
        }

//        saveOrUpdate(entity);
//        param.getItem().stream().forEach(item -> {
//            VojObjectiveQuestionOption option = new VojObjectiveQuestionOption();
//            option.setQuestionId(entity.getId());
//            option.setContent(item.getContent());
//            QueryWrapper<VojObjectiveQuestionOption> optionWrapper = new QueryWrapper<>();
//            optionWrapper.eq("question_id", entity.getId());
//            vojObjectiveQuestionOptionService.saveOrUpdate(option, optionWrapper);
//            if (item.getAnswer()){
//                VojObjectiveQuestionAnswer answer = new VojObjectiveQuestionAnswer();
//                answer.setQuestionId(entity.getId());
//                answer.setOptionId(option.getId());
//                QueryWrapper<VojObjectiveQuestionAnswer> answerWrapper = new QueryWrapper<>();
//                answerWrapper.eq("question_id", entity.getId());
//                answerWrapper.eq("option_id", option.getId());
//                vojObjectiveQuestionAnswerService.saveOrUpdate(answer, answerWrapper);
//            }
//        });
        // 保存选项和答案

        param.getItem().stream().forEach(item -> {
            VojObjectiveQuestionOption option = new VojObjectiveQuestionOption();
            option.setQuestionId(entity.getId());
            option.setContent(item.getContent());
            vojObjectiveQuestionOptionMapper.insert(option);
            if (item.getAnswer()){
                VojObjectiveQuestionAnswer answer = new VojObjectiveQuestionAnswer();
                answer.setQuestionId(entity.getId());
                answer.setOptionId(option.getId());
                vojObjectiveQuestionAnswerMapper.insert(answer);
            }
        });


        // 新增分类与标签
        String categoryId = param.getCategoryId();
        String tagId = param.getTagId();
        JSONArray categoryJson = JSON.parseArray(categoryId);
        JSONArray tagJson = JSON.parseArray(tagId);

        System.out.println(entity.getId());
        if ( categoryJson.size() == 0 ) {
            // 分类设置默认值
            categoryJson.add("uncategorized");
        }
        categoryJson.forEach(item -> {
            vojObjectiveQuestionsCategoryRelationshipsMapper.createCategoryRelationships(entity.getId(), item.toString());
        });

        if (tagJson.size() != 0){
            tagJson.forEach(item -> {
                vojObjectiveQuestionsTagRelationshipsMapper.createTagRelationships(entity.getId(), item.toString());
            });
        }
    }

    @Override
    public void delete(IdParam param) {
        vojObjectiveQuestionMapper.deleteById(param.getId());
        // 删除对应关系
        QueryWrapper<VojObjectiveQuestionsCategoryRelationships> categoryWrapper = new QueryWrapper<>();
        categoryWrapper.eq("question_id", param.getId());
        vojObjectiveQuestionsCategoryRelationshipsMapper.delete(categoryWrapper);
        QueryWrapper<VojObjectiveQuestionsTagRelationships> tagWrapper = new QueryWrapper<>();
        tagWrapper.eq("question_id", param.getId());
        vojObjectiveQuestionsTagRelationshipsMapper.delete(tagWrapper);
    }

    @Override
    public Page<VojObjectiveQuestionsListDto> list(VojObjectiveQuestionsListParam param) {
        Long companyId;
        UserCache userInfo = UserInfoShareHolder.getUserInfo();
        User user = userInfo.getUser();
        if (UserIdentifyEnum.superAdmin.getIdentify().equals(user.getIdentify())) {
            companyId = null;
        }else {
            companyId = userInfo.getCompanyId();
        }
        // 如果前端传来是 “All”, 那么不对这个选择条件进行添加，将字段设置为 null 或 ""
        if(param.getTagId() != null && param.getTagId().equals("All")) {
            param.setTagId("");
        }
        // 如果搜索框传来的是题号，将题号数据存入到 param 中
        if(param.getTitle() != null && param.getTitle().matches("^\\d+$") && param.getTitle().length() <= 8){
            param.setObjectiveProblemId(Integer.parseInt(param.getTitle()));
        }
        Integer total = vojObjectiveQuestionMapper.countList(param, companyId);
        Page<VojObjectiveQuestionsListDto> result = new PageDTO<>(param.getCurrent(), param.getSize(), total);
        Long offset = param.getOffset();
        List<VojObjectiveQuestionsDto> data = vojObjectiveQuestionMapper.list(param, companyId, offset);
        if (!CollectionUtils.isEmpty(data)){
            ArrayList<VojObjectiveQuestionsListDto> records = new ArrayList<>();
            Map<Long, List<VojObjectiveQuestionsDto>> collect = data.stream().collect(Collectors.groupingBy(VojObjectiveQuestionsDto::getId));
            collect.forEach((key, value) ->{
                if (!CollectionUtils.isEmpty(value)){
                    VojObjectiveQuestionsListDto entity = BeanUtil.copyProperties(value.get(0), VojObjectiveQuestionsListDto.class);

                    List<ObjectiveQuestionItem> itemList = value.stream().map(item -> {
                        ObjectiveQuestionItem questionItem = new ObjectiveQuestionItem();
                        questionItem.setId(item.getId());
                        questionItem.setContent(item.getContent());
                        questionItem.setAnswer(StringUtils.isEmpty(item.getAnswerId()) ? false : true);
                        return questionItem;
                    }).collect(Collectors.toList());
                    entity.setItemList(itemList);
                    records.add(entity);
                }
            });
            result.setRecords(records);
        }else{
            result.setRecords(new ArrayList<>());
        }
        return result;
    }

    @Override
    public void setPublic(IdParam param) {
        Long companyId = UserInfoShareHolder.getUserInfo().getCompanyId();
        VojObjectiveQuestion entity = new VojObjectiveQuestion();
        entity.setId(param.getId());
        entity.setCompanyId(companyId);
        vojObjectiveQuestionMapper.updateById(entity);
    }

    @Override
    public List<VojObjectiveQuestionsListDto> getProblemByIds(List<Long> ids){
        List<VojObjectiveQuestionsDto> data = vojObjectiveQuestionMapper.getProblemByIds(ids);
        List<VojObjectiveQuestionsListDto> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(data)){
            VojObjectiveQuestionsListDto entity = BeanUtil.copyProperties(data.get(0), VojObjectiveQuestionsListDto.class);
            entity.setCompanyName(redisUtil.getValueForMap(RedisKey.COMPANY_ID_NAME, data.get(0).getCompanyId().toString()));

            List<ObjectiveQuestionItem> collect = data.stream().map(item -> {
                ObjectiveQuestionItem questionItem = new ObjectiveQuestionItem();
                questionItem.setId(item.getId());
                questionItem.setContent(item.getContent());
                questionItem.setAnswer(StringUtils.isEmpty(item.getAnswerId()) ? false : true);
                return questionItem;
            }).collect(Collectors.toList());
            entity.setItemList(collect);
            result.add(entity);
        }else {
            throw new BusinessException(BusinessExceptionCode.INVALID_ID);
        }

        return result;
    }

    @Override
    public List<ObjectiveQuestionDTO> getObjectiveByRandom(Integer limit) {
        List<VojObjectiveQuestionsDto> data = vojObjectiveQuestionMapper.getObjectiveByRandom(limit);
        if (limit > data.size()) {
            throw ExceptionUtils.exception("题库中题目数量不足，不足以创建%s道客观题", limit);
        }
        return data.stream().map(e -> {
//            List<ObjectiveQuestionItem> items = JsonUtils.deserializeList(e.getItem(), ObjectiveQuestionItem.class);
            ObjectiveQuestionDTO entity = JsonUtils.deserialize(JsonUtils.serialize(e), ObjectiveQuestionDTO.class);
            // entity.setItemList(items);
            return entity;
        }).collect(Collectors.toList());
    }
}




